Author: dmacvicar
Date: Mon Jun 25 18:26:33 2007
New Revision: 39021
URL: http://svn.opensuse.org/viewcvs/yast?rev=39021&view=rev
Log:
lot of progress, ruby -> yast works fine.
yast -> ruby still segfaults when loading the
ruby module, but for one day it is a lot, backup!
Added:
branches/tmp/dmacvicar/ruby-yast/examples/ruby/ruby_from_ycp.ycp
branches/tmp/dmacvicar/ruby-yast/examples/ruby/ycp_from_ruby.rb
branches/tmp/dmacvicar/ruby-yast/src/ruby/
branches/tmp/dmacvicar/ruby-yast/src/ruby/CMakeLists.txt
branches/tmp/dmacvicar/ruby-yast/src/ruby/Makefile.am
branches/tmp/dmacvicar/ruby-yast/src/ruby/RubyLogger.cc
branches/tmp/dmacvicar/ruby-yast/src/ruby/RubyLogger.h
branches/tmp/dmacvicar/ruby-yast/src/ruby/Y2CCRuby.cc
branches/tmp/dmacvicar/ruby-yast/src/ruby/Y2CCRuby.h
branches/tmp/dmacvicar/ruby-yast/src/ruby/Y2RubyComponent.cc
branches/tmp/dmacvicar/ruby-yast/src/ruby/Y2RubyComponent.h
branches/tmp/dmacvicar/ruby-yast/src/ruby/Y2RubyTypeConv.cc
branches/tmp/dmacvicar/ruby-yast/src/ruby/Y2RubyTypeConv.h
branches/tmp/dmacvicar/ruby-yast/src/ruby/YCP.cc
branches/tmp/dmacvicar/ruby-yast/src/ruby/YCP.rb
branches/tmp/dmacvicar/ruby-yast/src/ruby/YRuby.cc
branches/tmp/dmacvicar/ruby-yast/src/ruby/YRuby.h
branches/tmp/dmacvicar/ruby-yast/src/ruby/YRubyNamespace.cc
branches/tmp/dmacvicar/ruby-yast/src/ruby/YRubyNamespace.h
branches/tmp/dmacvicar/ruby-yast/src/ruby/YaPI.pm.in
Modified:
branches/tmp/dmacvicar/ruby-yast/cmake/modules/FindYast.cmake
branches/tmp/dmacvicar/ruby-yast/examples/ruby/test1.rb
branches/tmp/dmacvicar/ruby-yast/src/CMakeLists.txt
branches/tmp/dmacvicar/ruby-yast/src/swig/yast.i
Modified: branches/tmp/dmacvicar/ruby-yast/cmake/modules/FindYast.cmake
URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/dmacvicar/ruby-yast/cmake/modules/FindYast.cmake?rev=39021&r1=39020&r2=39021&view=diff
==============================================================================
--- branches/tmp/dmacvicar/ruby-yast/cmake/modules/FindYast.cmake (original)
+++ branches/tmp/dmacvicar/ruby-yast/cmake/modules/FindYast.cmake Mon Jun 25 18:26:33 2007
@@ -9,10 +9,13 @@
set(YAST_YCP_LIBRARY)
FIND_PATH(YAST_INCLUDE_DIR Y2.h
+ ${CMAKE_INSTALL_PREFIX}/include/YaST2
/usr/include/YaST2
/usr/local/include/YaST2
)
+SET(YAST_PLUGIN_DIR ${CMAKE_INSTALL_PREFIX}/lib/YaST2/plugin)
+
FIND_LIBRARY(YAST_LIBRARY NAMES y2
PATHS
/usr/lib
@@ -34,6 +37,7 @@
if(YAST_INCLUDE_DIR AND YAST_LIBRARY AND YAST_YCP_LIBRARY)
MESSAGE( STATUS "YaST2 found: includes in ${YAST_INCLUDE_DIR}, library in ${YAST_LIBRARY}")
+ MESSAGE( STATUS " plugins in ${YAST_PLUGIN_DIR}")
set(YAST_FOUND TRUE)
else(YAST_INCLUDE_DIR AND YAST_LIBRARY AND YAST_YCP_LIBRARY)
MESSAGE( STATUS "YaST2 not found")
Added: branches/tmp/dmacvicar/ruby-yast/examples/ruby/ruby_from_ycp.ycp
URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/dmacvicar/ruby-yast/examples/ruby/ruby_from_ycp.ycp?rev=39021&view=auto
==============================================================================
--- branches/tmp/dmacvicar/ruby-yast/examples/ruby/ruby_from_ycp.ycp (added)
+++ branches/tmp/dmacvicar/ruby-yast/examples/ruby/ruby_from_ycp.ycp Mon Jun 25 18:26:33 2007
@@ -0,0 +1,13 @@
+
+{
+ import "Duncan";
+ string result = multiply_by_eight(10);
+ UI::OpenDialog(
+ `VBox(
+ `Label(result),
+ `PushButton("OK")
+ )
+ );
+ UI::UserInput();
+ UI::CloseDialog();
+}
\ No newline at end of file
Modified: branches/tmp/dmacvicar/ruby-yast/examples/ruby/test1.rb
URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/dmacvicar/ruby-yast/examples/ruby/test1.rb?rev=39021&r1=39020&r2=39021&view=diff
==============================================================================
--- branches/tmp/dmacvicar/ruby-yast/examples/ruby/test1.rb (original)
+++ branches/tmp/dmacvicar/ruby-yast/examples/ruby/test1.rb Mon Jun 25 18:26:33 2007
@@ -13,11 +13,31 @@
component = Y2ComponentBroker.get_namespace_component("Arch");
#puts component.methods
#Y2Namespace *ns = c->import(RSTRING (namespace_name)->ptr);
-ns = get_ns("Arch")
+nsname = "Arch"
+fncname = "sparc32"
+ns = get_ns(nsname)
#/**/
-t = Type.from_signature("bool()")
-puts t
-function = ns.create_function_call("sparc32", t)
+#t = Type.from_signature("bool()")
+#puts t
+sym = ns.table.find(fncname);
+puts sym.class
+if (sym.nil?)
+ raise ("No such symbol #{nsname}::#{fncname}")
+elsif (sym.sentry.is_variable or sym.sentry.reference? )
+ # set the variable
+ #ret_yv = YCP_getset_variable (aTHX_ ns_name, sym_te->sentry (), args);
+else
+ fnccall = ns.create_function_call(fncname, nil)
+ if fnccall.nil?
+ raise("No such function #{nsname}::#{fncname}")
+ end
+end
+exit
+
+h = ns.lookup_symbol("sparc32")
+puts h.class
+exit
+function = ns.create_function_call("sparc32",0)
#call->appendParameter (v);
function.finish_parameters
res = function.evaluate_call
Added: branches/tmp/dmacvicar/ruby-yast/examples/ruby/ycp_from_ruby.rb
URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/dmacvicar/ruby-yast/examples/ruby/ycp_from_ruby.rb?rev=39021&view=auto
==============================================================================
--- branches/tmp/dmacvicar/ruby-yast/examples/ruby/ycp_from_ruby.rb (added)
+++ branches/tmp/dmacvicar/ruby-yast/examples/ruby/ycp_from_ruby.rb Mon Jun 25 18:26:33 2007
@@ -0,0 +1,18 @@
+require 'yast'
+
+# m = YaST::Module.new("Arch")
+# puts m.sparc32
+# puts m.arch_short
+# puts m.is_xen
+
+m = YaST::Module.new("Popup")
+m.Message("Hello")
+
+exit
+m = YaST::Module.new("Storage")
+dp = m.GetDiskPartition("/dev/sda1")
+dp.each do | key, value |
+ puts "#{key} #{value}"
+end
+
+
Modified: branches/tmp/dmacvicar/ruby-yast/src/CMakeLists.txt
URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/dmacvicar/ruby-yast/src/CMakeLists.txt?rev=39021&r1=39020&r2=39021&view=diff
==============================================================================
--- branches/tmp/dmacvicar/ruby-yast/src/CMakeLists.txt (original)
+++ branches/tmp/dmacvicar/ruby-yast/src/CMakeLists.txt Mon Jun 25 18:26:33 2007
@@ -1 +1,2 @@
-ADD_SUBDIRECTORY(swig)
\ No newline at end of file
+ADD_SUBDIRECTORY(swig)
+ADD_SUBDIRECTORY(ruby)
\ No newline at end of file
Added: branches/tmp/dmacvicar/ruby-yast/src/ruby/CMakeLists.txt
URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/dmacvicar/ruby-yast/src/ruby/CMakeLists.txt?rev=39021&view=auto
==============================================================================
--- branches/tmp/dmacvicar/ruby-yast/src/ruby/CMakeLists.txt (added)
+++ branches/tmp/dmacvicar/ruby-yast/src/ruby/CMakeLists.txt Mon Jun 25 18:26:33 2007
@@ -0,0 +1,45 @@
+
+ADD_DEFINITIONS(-DY2LOG=\\\"Ruby\\\")
+
+SET(yast_ruby_module_SRCS
+ YCP.cc
+ Y2RubyTypeConv.cc
+ RubyLogger.cc
+ RubyLogger.h
+)
+
+SET(ruby_yast_plugin_SRCS
+ RubyLogger.cc
+ Y2CCRuby.cc
+ Y2RubyComponent.cc
+ YRuby.cc
+ YRubyNamespace.cc
+ Y2RubyTypeConv.cc
+)
+
+SET(ruby_yast_plugin_HEADERS
+ RubyLogger.h
+ Y2CCRuby.h
+ Y2RubyComponent.h
+ YRuby.h
+ YRubyNamespace.h )
+
+INCLUDE_DIRECTORIES( ${RUBY_INCLUDE_PATH} )
+INCLUDE_DIRECTORIES( ${YAST_INCLUDE_DIR} )
+
+ADD_LIBRARY( yast SHARED ${yast_ruby_module_SRCS})
+SET_TARGET_PROPERTIES( yast PROPERTIES PREFIX "" )
+TARGET_LINK_LIBRARIES( yast ${YAST_LIBRARY} )
+TARGET_LINK_LIBRARIES( yast ${YAST_YCP_LIBRARY} )
+TARGET_LINK_LIBRARIES( yast ${YAST_PLUGIN_WFM_LIBRARY} )
+TARGET_LINK_LIBRARIES( yast ${RUBY_LIBRARY} )
+INSTALL(TARGETS yast LIBRARY DESTINATION ${RUBY_ARCH_DIR} )
+
+ADD_LIBRARY( py2lang_ruby SHARED ${ruby_yast_plugin_SRCS})
+TARGET_LINK_LIBRARIES( py2lang_ruby ${YAST_LIBRARY} )
+TARGET_LINK_LIBRARIES( py2lang_ruby ${YAST_YCP_LIBRARY} )
+TARGET_LINK_LIBRARIES( py2lang_ruby ${YAST_PLUGIN_WFM_LIBRARY} )
+TARGET_LINK_LIBRARIES( py2lang_ruby ${RUBY_LIBRARY} )
+INSTALL(TARGETS py2lang_ruby LIBRARY DESTINATION ${YAST_PLUGIN_DIR} )
+
+#SET_TARGET_PROPERTIES( y2lang_ruby PROPERTIES PREFIX "" )
\ No newline at end of file
Added: branches/tmp/dmacvicar/ruby-yast/src/ruby/Makefile.am
URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/dmacvicar/ruby-yast/src/ruby/Makefile.am?rev=39021&view=auto
==============================================================================
--- branches/tmp/dmacvicar/ruby-yast/src/ruby/Makefile.am (added)
+++ branches/tmp/dmacvicar/ruby-yast/src/ruby/Makefile.am Mon Jun 25 18:26:33 2007
@@ -0,0 +1,93 @@
+#
+# Makefile.am for perl-bindings/src
+#
+
+AM_CXXFLAGS = -DY2LOG=\"Perl\" -DMODULEDIR=\"$(moduledir)\"
+
+MY_PERL_VENDORARCH = $(subst /usr,$(prefix),$(PERL_VENDORARCH))
+perlpmdir = $(MY_PERL_VENDORARCH)/YaST
+perlsodir = $(MY_PERL_VENDORARCH)/auto/YaST/YCP
+
+perlpm_DATA = YCP.pm
+
+# plugin, libtool forces 'lib' prefix
+plugin_LTLIBRARIES = libpy2lang_perl.la
+noinst_LTLIBRARIES = liby2lang_perl.la
+perlso_LTLIBRARIES = libYCP.la
+
+# binary part of the Perl module
+libYCP_la_SOURCES = \
+ $(liby2lang_perl_la_SOURCES) \
+ YCP.cc \
+ PerlLogger.cc PerlLogger.h
+
+
+# are there enough yast libraries?
+# check with y2base, integrate them like y2pm does
+# Originally, of the py2* there was only py2plugin here
+# with the assumption that it would bring in the other plugins.
+# But it does not work.
+libYCP_la_LDFLAGS = $(PERL_LDFLAGS) \
+ -L$(libdir) -L$(plugindir) \
+ -Xlinker --whole-archive \
+ -lpy2scr \
+ -lpy2wfm \
+ -lscr -lyui \
+ -lycp -ly2 \
+ -Xlinker --no-whole-archive \
+ ${ZYPP_LIBS} -ly2util \
+ -version-info 2:0
+
+
+libpy2lang_perl_la_LDFLAGS = -version-info 2:0
+
+liby2lang_perl_la_LDFLAGS = -version-info 2:0
+
+
+# the yast libraries are apparently necessary when we're loaded by perl.
+libpy2lang_perl_la_LIBADD = $(PERL_LDFLAGS) \
+ -L$(libdir) -L$(plugindir) \
+ -lycp -ly2 ${ZYPP_LIBS} -ly2util
+#libpy2lang_perl_la_LIBADD = $(PERL_LDFLAGS)
+
+liby2lang_perl_la_LIBADD = $(PERL_LDFLAGS)
+
+
+liby2lang_perl_la_SOURCES = \
+ YPerl.cc YPerl.h \
+ perlxsi.c
+
+# Auto-generated stub for dynamic loading of Perl modules.
+# And also register the interface to the YCP module
+## which is linked in already and won't be in the standard Perl location.
+#
+# This results in a linker warning:
+# *** Warning: Linking the shared library libpy2lang_perl.la against the
+# *** static library /usr/lib/perl5/.../DynaLoader.a is not portable!
+#
+# According to mls@suse.de this warning can safely be disregarded:
+# The SuSE DynaLoader is compiled with -fPIC for just this situation.
+#
+# -- sh@suse.de 2003-07-24
+perlxsi.c:
+ perl -MExtUtils::Embed -e xsinit -- -o perlxsi.c -std
+# See "man perlembed"
+
+
+# the plugin adds the liby2 component interface
+
+libpy2lang_perl_la_SOURCES = \
+ $(liby2lang_perl_la_SOURCES) \
+ Y2CCPerl.cc Y2CCPerl.h \
+ YPerlNamespace.cc YPerlNamespace.h \
+ Y2PerlComponent.cc Y2PerlComponent.h
+
+CLEANFILES = \
+ perlxsi.c
+
+INCLUDES = -I$(srcdir)/include -I$(includedir) ${ZYPP_CFLAGS}
+
+# generated from YaPI.pm.in by configure
+nodist_module_DATA = YaPI.pm
+
+EXTRA_DIST = $(perlpm_DATA) $(module_DATA)
Added: branches/tmp/dmacvicar/ruby-yast/src/ruby/RubyLogger.cc
URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/dmacvicar/ruby-yast/src/ruby/RubyLogger.cc?rev=39021&view=auto
==============================================================================
--- branches/tmp/dmacvicar/ruby-yast/src/ruby/RubyLogger.cc (added)
+++ branches/tmp/dmacvicar/ruby-yast/src/ruby/RubyLogger.cc Mon Jun 25 18:26:33 2007
@@ -0,0 +1,31 @@
+#include "RubyLogger.h"
+#include
+
+extern ExecutionEnvironment ee;
+
+void
+RubyLogger::error (string error_message)
+{
+ y2_logger (LOG_ERROR,"Ruby",ee.filename ().c_str ()
+ ,ee.linenumber (),"","%s", error_message.c_str ());
+}
+
+
+void
+RubyLogger::warning (string warning_message)
+{
+ y2_logger (LOG_ERROR,"Ruby",ee.filename ().c_str ()
+ ,ee.linenumber (),"","%s", warning_message.c_str ());
+}
+
+RubyLogger*
+RubyLogger::instance ()
+{
+ if ( ! m_rubylogger )
+ {
+ m_rubylogger = new RubyLogger ();
+ }
+ return m_rubylogger;
+}
+
+RubyLogger* RubyLogger::m_rubylogger = NULL;
Added: branches/tmp/dmacvicar/ruby-yast/src/ruby/RubyLogger.h
URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/dmacvicar/ruby-yast/src/ruby/RubyLogger.h?rev=39021&view=auto
==============================================================================
--- branches/tmp/dmacvicar/ruby-yast/src/ruby/RubyLogger.h (added)
+++ branches/tmp/dmacvicar/ruby-yast/src/ruby/RubyLogger.h Mon Jun 25 18:26:33 2007
@@ -0,0 +1,23 @@
+#ifndef RubyLogger_h
+#define RubyLogger_h
+
+#include "ycp/y2log.h"
+
+/**
+ * @short A class to provide logging for Ruby bindings errors and warning
+ */
+class RubyLogger : public Logger
+{
+ static RubyLogger* m_rubylogger;
+
+public:
+ void error (string message);
+ void warning (string message);
+
+ static RubyLogger* instance ();
+};
+
+#endif // ifndef RubyLogger_h
+
+
+// EOF
Added: branches/tmp/dmacvicar/ruby-yast/src/ruby/Y2CCRuby.cc
URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/dmacvicar/ruby-yast/src/ruby/Y2CCRuby.cc?rev=39021&view=auto
==============================================================================
--- branches/tmp/dmacvicar/ruby-yast/src/ruby/Y2CCRuby.cc (added)
+++ branches/tmp/dmacvicar/ruby-yast/src/ruby/Y2CCRuby.cc Mon Jun 25 18:26:33 2007
@@ -0,0 +1,43 @@
+#include "Y2CCRuby.h"
+#include
+#define y2log_component "Y2Ruby"
+#include
+
+// This is very important: We create one global variable of
+// Y2CCRuby. Its constructor will register it automatically to
+// the Y2ComponentBroker, so that will be able to find it.
+// This all happens before main() is called!
+
+Y2CCRuby g_y2ccruby;
+
+Y2Component *Y2CCRuby::provideNamespace (const char *name)
+{
+ y2debug ("Y2CCRuby::provideNamespace %s", name);
+ if (strcmp (name, "Ruby") == 0)
+ {
+ // low level functions
+
+ // leave implementation to later
+ return 0;
+ }
+ else
+ {
+ // is there a ruby module?
+ // must be the same in Y2CCRuby and Y2RubyComponent
+ string module = YCPPathSearch::find (YCPPathSearch::Module, string (name) + ".rb");
+ y2milestone("Find result '%s'", module.c_str());
+ if (!module.empty ())
+ {
+ if (!cruby)
+ {
+ y2milestone("new ruby component");
+ cruby = new Y2RubyComponent();
+ }
+ y2milestone("returning existing ruby component");
+ return cruby;
+ }
+
+ // let someone else try creating the namespace
+ return 0;
+ }
+}
Added: branches/tmp/dmacvicar/ruby-yast/src/ruby/Y2CCRuby.h
URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/dmacvicar/ruby-yast/src/ruby/Y2CCRuby.h?rev=39021&view=auto
==============================================================================
--- branches/tmp/dmacvicar/ruby-yast/src/ruby/Y2CCRuby.h (added)
+++ branches/tmp/dmacvicar/ruby-yast/src/ruby/Y2CCRuby.h Mon Jun 25 18:26:33 2007
@@ -0,0 +1,75 @@
+/*-----------------------------------------------------------*- c++ -*-\
+| |
+| __ __ ____ _____ ____ |
+| \ \ / /_ _/ ___|_ _|___ \ |
+| \ V / _` \___ \ | | __) | |
+| | | (_| |___) || | / __/ |
+| |_|\__,_|____/ |_| |_____| |
+| |
+| core system |
+| (C) SuSE Linux AG |
+\----------------------------------------------------------------------/
+
+ File: Y2CCRuby.h
+
+ Author: Stefan Hundhammer
+
+/-*/
+
+
+#ifndef _Y2CCRuby_h
+#define _Y2CCRuby_h
+
+#include "Y2RubyComponent.h"
+
+/**
+ * @short Y2ComponentCreator that creates Ruby-from-YCP bindings.
+ *
+ * A Y2ComponentCreator is an object that can create components.
+ * It receives a component name and - if it knows how to create
+ * such a component - returns a newly created component of this
+ * type. Y2CCRuby can create components with the name "Ruby".
+ */
+class Y2CCRuby : public Y2ComponentCreator
+{
+private:
+ Y2Component *cruby;
+
+public:
+ /**
+ * Creates a Ruby component creator
+ */
+ Y2CCRuby() : Y2ComponentCreator( Y2ComponentBroker::BUILTIN ),
+ cruby (0) {};
+
+ ~Y2CCRuby () {
+ if (cruby)
+ delete cruby;
+ }
+
+ /**
+ * Returns true, since the Ruby component is a YaST2 server.
+ */
+ bool isServerCreator() const { return true; };
+
+ /**
+ * Creates a new Ruby component.
+ */
+ Y2Component *create( const char * name ) const
+ {
+ // create as many as requested, they all share the static YRuby anyway
+ if ( ! strcmp( name, "ruby") ) return new Y2RubyComponent();
+ else return 0;
+ }
+
+ /**
+ * always returns the same component, deletes it finally
+ */
+ Y2Component *provideNamespace (const char *name);
+
+};
+
+#endif // ifndef _Y2CCRuby_h
+
+
+// EOF
Added: branches/tmp/dmacvicar/ruby-yast/src/ruby/Y2RubyComponent.cc
URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/dmacvicar/ruby-yast/src/ruby/Y2RubyComponent.cc?rev=39021&view=auto
==============================================================================
--- branches/tmp/dmacvicar/ruby-yast/src/ruby/Y2RubyComponent.cc (added)
+++ branches/tmp/dmacvicar/ruby-yast/src/ruby/Y2RubyComponent.cc Mon Jun 25 18:26:33 2007
@@ -0,0 +1,54 @@
+#define y2log_component "Y2Ruby"
+#include
+#include
+
+#include "Y2RubyComponent.h"
+#include "YRuby.h"
+#include "YRubyNamespace.h"
+using std::string;
+
+
+Y2RubyComponent::Y2RubyComponent()
+{
+ // Actual creation of a Ruby interpreter is postponed until one of the
+ // YRuby static methods is used. They handle that.
+
+ y2milestone( "Creating Y2RubyComponent" );
+}
+
+
+Y2RubyComponent::~Y2RubyComponent()
+{
+ y2milestone( "Destroying Y2RubyComponent" );
+ YRuby::destroy();
+}
+
+
+void Y2RubyComponent::result( const YCPValue & )
+{}
+
+
+Y2Namespace *Y2RubyComponent::import (const char* name)
+{
+ y2milestone("Creating namespace for import '%s'", name);
+ // TODO where to look for it
+ // must be the same in Y2CCRuby and Y2RubyComponent
+ string module = YCPPathSearch::find (YCPPathSearch::Module, string (name) + ".rb");
+ if (module.empty ())
+ {
+ y2internal ("Couldn't find %s after Y2CCRuby pointed to us", name);
+ return NULL;
+ }
+ y2milestone("Found in '%s'", module.c_str());
+ module.erase (module.size () - 3 /* strlen (".pm") */);
+ YCPList args;
+ args->add (YCPString(/*module*/ name));
+
+ // load it
+ YRuby::loadModule (args);
+ y2milestone("Module '%s' loaded", name);
+ // introspect, create data structures for the interpreter
+ Y2Namespace *ns = new YRubyNamespace (name);
+
+ return ns;
+}
Added: branches/tmp/dmacvicar/ruby-yast/src/ruby/Y2RubyComponent.h
URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/dmacvicar/ruby-yast/src/ruby/Y2RubyComponent.h?rev=39021&view=auto
==============================================================================
--- branches/tmp/dmacvicar/ruby-yast/src/ruby/Y2RubyComponent.h (added)
+++ branches/tmp/dmacvicar/ruby-yast/src/ruby/Y2RubyComponent.h Mon Jun 25 18:26:33 2007
@@ -0,0 +1,55 @@
+#ifndef Y2RubyComponent_h
+#define Y2RubyComponent_h
+
+#include "Y2.h"
+
+
+/**
+ * @short YaST2 Component: Ruby bindings
+ */
+class Y2RubyComponent : public Y2Component
+{
+public:
+ /**
+ * Constructor.
+ */
+ Y2RubyComponent();
+
+ /**
+ * Destructor.
+ */
+ ~Y2RubyComponent();
+
+ /**
+ * The name of this component.
+ */
+ string name() const { return "perl"; }
+
+ /**
+ * Is called by the generic frontend when the session is finished.
+ */
+ void result( const YCPValue & result );
+
+ /**
+ * Implements the Ruby:: functions.
+ **/
+// not yet, prototype the transparent bindings first
+// YCPValue evaluate( const YCPValue & val );
+
+ /**
+ * Try to import a given namespace. This method is used
+ * for transparent handling of namespaces (YCP modules)
+ * through whole YaST.
+ * @param name_space the name of the required namespace
+ * @return on errors, NULL should be returned. The
+ * error reporting must be done by the component itself
+ * (typically using y2log). On success, the method
+ * should return a proper instance of the imported namespace
+ * ready to be used. The returned instance is still owned
+ * by the component, any other part of YaST will try to
+ * free it. Thus, it's possible to share the instance.
+ */
+ Y2Namespace *import (const char* name);
+};
+
+#endif // Y2RubyComponent_h
Added: branches/tmp/dmacvicar/ruby-yast/src/ruby/Y2RubyTypeConv.cc
URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/dmacvicar/ruby-yast/src/ruby/Y2RubyTypeConv.cc?rev=39021&view=auto
==============================================================================
--- branches/tmp/dmacvicar/ruby-yast/src/ruby/Y2RubyTypeConv.cc (added)
+++ branches/tmp/dmacvicar/ruby-yast/src/ruby/Y2RubyTypeConv.cc Mon Jun 25 18:26:33 2007
@@ -0,0 +1,107 @@
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "Y2RubyTypeConv.h"
+
+/**
+ * Converts a YCPValue into a Ruby Value
+ * Supports neested lists using recursion.
+ */
+extern "C" VALUE
+ycpvalue_2_rbvalue( YCPValue ycpval )
+{
+ // 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 (ycpval->isVoid())
+ {
+ return Qnil;
+ }
+ else if (ycpval->isBoolean())
+ {
+ return ycpval->asBoolean()->value() ? Qtrue : Qfalse;
+ }
+ else if (ycpval->isString())
+ {
+ return rb_str_new2(ycpval->asString()->value().c_str());
+ }
+ else if (ycpval->isInteger())
+ {
+ return INT2NUM( ycpval->asInteger()->value() );
+ }
+ else if ( ycpval->isMap() )
+ {
+ VALUE rbhash;
+ rbhash = rb_hash_new();
+ YCPMap map = ycpval->asMap();
+ y2internal("map size %d\n", map.size());
+
+ for ( YCPMapIterator it = map.begin(); it != map.end(); ++it )
+ {
+ YCPValue key = it.key();
+ YCPValue value = it.value();
+ rb_hash_aset(rbhash, ycpvalue_2_rbvalue(key), ycpvalue_2_rbvalue(value) );
+ }
+ return rbhash;
+ }
+ else if (ycpval->isList())
+ {
+ VALUE rblist;
+ rblist = rb_ary_new();
+ YCPList list = ycpval->asList();
+ y2internal("list size %d\n",list.size());
+ for (int i=0; i < list.size(); i++)
+ {
+ rb_ary_push( rblist, ycpvalue_2_rbvalue(list.value(i)));
+ }
+ return rblist;
+ }
+ rb_raise( rb_eRuntimeError, "Conversion of YCP type %s not supported", ycpval->toString().c_str() );
+ return Qnil;
+}
+
+// isEmpty size add remove (value n) toString
+YCPValue
+rbvalue_2_ycpvalue( VALUE value )
+{
+ // TODO conver integers, and add support for lists, ah, and boleans!
+ switch (TYPE(value))
+ {
+ case T_STRING:
+ return YCPString(RSTRING (value)->ptr);
+ break;
+ case T_TRUE:
+ return YCPBoolean(true);
+ break;
+ case T_FALSE:
+ return YCPBoolean(false);
+ break;
+ case T_FIXNUM:
+ return YCPInteger(NUM2LONG(value));
+ break;
+ case T_FLOAT:
+ return YCPFloat(NUM2DBL(value));
+ break;
+ case T_ARRAY:
+ // FIXME
+ break;
+ case T_HASH:
+ // FIXME
+ break;
+ case T_DATA:
+ rb_raise( rb_eRuntimeError, "Object");
+ break;
+ std::cout << TYPE(value) << std::endl;
+ rb_raise( rb_eRuntimeError, "Conversion of Ruby type not supported");
+ return YCPValue();
+ }
+}
Added: branches/tmp/dmacvicar/ruby-yast/src/ruby/Y2RubyTypeConv.h
URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/dmacvicar/ruby-yast/src/ruby/Y2RubyTypeConv.h?rev=39021&view=auto
==============================================================================
--- branches/tmp/dmacvicar/ruby-yast/src/ruby/Y2RubyTypeConv.h (added)
+++ branches/tmp/dmacvicar/ruby-yast/src/ruby/Y2RubyTypeConv.h Mon Jun 25 18:26:33 2007
@@ -0,0 +1,23 @@
+
+#ifndef Y2RUBYTYPECONV_H
+#define Y2RUBYTYPECONV_H
+
+#include
+#include "ruby.h"
+
+/**
+ * Converts a YCPValue into a Ruby Value
+ * Supports neested lists using recursion.
+ */
+extern "C" VALUE
+ycpvalue_2_rbvalue( YCPValue ycpval );
+
+/**
+ * Converts a Ruby Value into a YCPValue
+ * Supports neested lists using recursion.
+ */
+YCPValue
+rbvalue_2_ycpvalue( VALUE value );
+
+#endif
+
Added: branches/tmp/dmacvicar/ruby-yast/src/ruby/YCP.cc
URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/dmacvicar/ruby-yast/src/ruby/YCP.cc?rev=39021&view=auto
==============================================================================
--- branches/tmp/dmacvicar/ruby-yast/src/ruby/YCP.cc (added)
+++ branches/tmp/dmacvicar/ruby-yast/src/ruby/YCP.cc Mon Jun 25 18:26:33 2007
@@ -0,0 +1,679 @@
+// #include
+// #include
+#include
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "ruby.h"
+
+//#include "YRuby.h"
+#include "RubyLogger.h"
+#include "Y2RubyTypeConv.h"
+
+static VALUE rb_mYaST;
+static VALUE rb_cBroker;
+
+// make the compiler happy when
+// calling rb_define_method()
+typedef VALUE (ruby_method)(...);
+
+// more useful macros
+#define RB_FINALIZER(func) ((void (*)(...))func)
+
+// this macro saves us from typing
+// (ruby_method*) & method_name
+// in rb_define_method
+#define RB_METHOD(func) ((VALUE (*)(...))func)
+
+Y2Component *owned_uic = 0;
+Y2Component *owned_wfmc = 0;
+
+static
+Y2Namespace *
+getNs (const char * ns_name, const char * func_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);
+ }
+ else
+ {
+ ns->initialize ();
+ }
+ return ns;
+}
+
+typedef struct brokerinfo
+{
+ Y2Component *component;
+ Y2Namespace *ns;
+}
+BrokerInfo;
+
+// mark for garbage collection
+// NOT USED, ONLY WHEN USING DATA_WRAP_STRUCT
+void
+yast_module_mark( BrokerInfo *info )
+{}
+
+// dispose a namespace
+// NOT USED, ONLY WHEN USING DATA_WRAP_STRUCT
+void
+yast_module_free( BrokerInfo *info )
+{
+ //std::cout << "Deleting namespace." << std::endl;
+ //delete info;
+}
+
+VALUE
+yast_module_allocate( VALUE klass )
+{
+ BrokerInfo *info = new BrokerInfo;
+ return Data_Wrap_Struct( klass, yast_module_mark, RB_FINALIZER(yast_module_free), info );
+}
+
+VALUE
+yast_module_initialize( VALUE self, VALUE param_ns_name )
+{
+ Check_Type(param_ns_name, T_STRING);
+ rb_iv_set(self, "@namespace_name", param_ns_name);
+ return self;
+}
+
+VALUE
+yast_module_methods( VALUE self )
+{
+ return Qnil;
+}
+
+VALUE
+yast_module_proxy_method( int argc, VALUE *argv, VALUE self )
+{
+ VALUE symbol = argv[0];
+ // the func name (1st argument, is a symbol
+ // lets convert it to string
+ VALUE symbol_str = rb_funcall(symbol, rb_intern("to_s"), 0);
+ y2internal("Function: [%s] params: [%d]\n", RSTRING(symbol_str)->ptr, argc);
+
+ //Check_Type(argv[0], T_STRING);
+ //y2internal(RSTRING (symbol)->ptr);
+ //Data_Get_Struct( self, class Y2Namespace, ns );
+ //ns = gNameSpaces[self];
+
+ Y2Component *c;
+ VALUE namespace_name = rb_iv_get(self, "@namespace_name");
+ 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());
+
+ // import the namespace
+ //Y2Namespace *ns = c->import(RSTRING (namespace_name)->ptr);
+ Y2Namespace *ns = getNs( RSTRING (namespace_name)->ptr, RSTRING(symbol_str)->ptr);
+ if (ns == NULL)
+ {
+ rb_raise( rb_eRuntimeError, "Component cannot import namespace %s", RSTRING (namespace_name)->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);
+
+ if (sym_te == NULL)
+ {
+ y2error ("No such symbol %s::%s", RSTRING (namespace_name)->ptr, RSTRING(symbol_str)->ptr);
+ rb_raise( rb_eNameError, "YCP symbol '%s' not found in namespace '%s'", RSTRING(symbol_str)->ptr, RSTRING (namespace_name)->ptr );
+ return Qnil;
+ }
+
+ if (sym_te->sentry ()->isVariable () ||
+ sym_te->sentry ()->isReference ())
+ {
+ // set the variable
+ //ret_yv = YCP_getset_variable (aTHX_ ns_name, sym_te->sentry (), args);
+ }
+ else
+ { // no indent yet
+ Y2Function* call = ns->createFunctionCall (RSTRING(symbol_str)->ptr, 0 /*Type::fromSignature("list<string>()")*/);
+
+ if (call == NULL)
+ {
+ y2internal ("Cannot create function call %s\n", RSTRING(symbol_str)->ptr);
+ return 4;
+ }
+
+ // add the parameters
+ for (int i=1; itoString());
+ call->appendParameter (v);
+ }
+ call->finishParameters ();
+
+ YCPValue res = call->evaluateCall ();
+ delete call;
+ y2internal ("Call succeded\n");
+ //y2internal ("Result: %i\n", res->asList()->size());
+ return ycpvalue_2_rbvalue(res);
+ }
+ return Qnil;
+}
+
+
+extern "C"
+{
+ void
+ Init_yast()
+ {
+ YCPPathSearch::initialize ();
+
+
+ for ( list<string>::const_iterator it = YCPPathSearch::searchListBegin (YCPPathSearch::Module); it != YCPPathSearch::searchListEnd (YCPPathSearch::Module) ; ++it )
+ {
+ y2internal("%s\n", (*it).c_str() );
+ }
+
+ string module = YCPPathSearch::find (YCPPathSearch::Module, string ("MyModule.ycp"));
+ y2internal("%s\n", module.c_str() );
+
+ rb_mYaST = rb_define_module("YaST");
+
+ // CIMClient
+ 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);
+ }
+}
+
+
+// forward declaration
+//YCPValue YCP_call_SCR (pTHX_ const char * func_name, const vector& args);
+//YCPValue YCP_getset_variable (pTHX_ const char * ns_name, SymbolEntryPtr var_se, const vector& args);
+
+// XS(XS_YCP_y2_logger); /* prototype to pass -Wmissing-prototypes */
+// XS(XS_YCP_y2_logger)
+// {
+// // defines "items", the number of arguments
+// dXSARGS;
+// if (items != 6)
+// {
+// y2internal ("y2_logger must have 6 arguments");
+// XSRETURN_EMPTY;
+// }
+// loglevel_t level = (loglevel_t) SvIV (ST (0));
+// const char * comp = SvPV_nolen (ST (1));
+// const char * file = SvPV_nolen (ST (2));
+// int line = SvIV (ST (3));
+// const char * function = SvPV_nolen (ST (4));
+// const char * message = SvPV_nolen (ST (5));
+// y2_logger (level, comp, file, line, function, "%s", message);
+// XSRETURN_EMPTY;
+// }
+
+// XS(XS_YCP_call_ycp); /* prototype to pass -Wmissing-prototypes */
+// XS(XS_YCP_call_ycp)
+// {
+// // defines "items", the number of arguments
+// dXSARGS; // must be called only once per xsub because it calls POPMARK
+//
+// /*
+// * Plan:
+// * get the namespace name
+// * get the function name
+// * get the ns from the component broker (importing it, if necessary)
+// * find the function
+// * check its declaration, trying to convert the actual parameters
+// * to the desired ones
+// * call it
+// * pass the return value - if it's a list and perl wanted a list, so be it
+// */
+//
+// // calling convention:
+// // namespace name (without trailing ::)
+// // function name
+// // function arguments
+// if (items < 2 || !SvPOK (ST (0)) || !SvPOK (ST (1)))
+// {
+// y2internal ("Ruby called YCP without specifying a namespace and a name");
+// XSRETURN_EMPTY;
+// }
+//
+// const char * ns_name = SvPV_nolen (ST (0));
+// const char * func_name = SvPV_nolen (ST (1));
+//
+// // The perl interpreter must not get reinitialized.
+// // Therefore we push what we got (aTHX) to YRuby so that it does
+// // not try to construct its own.
+// YRuby::acceptInterpreter (aTHX); // access the singleton object
+// YRuby *yperl = YRuby::yRuby (); // access the singleton object
+//
+// YCPValue ret_yv = YCPNull ();
+//
+// // access the parameters via a vector because using dXSARGS more
+// // than once per XSUB call messes up Ruby call stacks
+// vector args;
+// args.reserve (items - 2);
+// I32 i;
+// for (i = 2; i < items; ++i)
+// {
+// args.push_back (ST (i));
+// }
+//
+// // this is a hack before the builtin namespaces get a uniform interface:
+// if (! strcmp (ns_name, "SCR"))
+// {
+// ret_yv = YCP_call_SCR (aTHX_ func_name, args);
+// }
+// else
+// {
+// Y2Namespace *ns = getNs (ns_name, func_name);
+// if (ns == NULL)
+// {
+// XSRETURN_EMPTY;
+// }
+//
+// // we want either a function or a variable
+// // so find a symbol of an unspecified category
+// TableEntry *sym_te = ns->table ()->find (func_name);
+//
+// if (sym_te == NULL)
+// {
+// y2error ("No such symbol %s::%s", ns_name, func_name);
+// XSRETURN_EMPTY;
+// }
+//
+// if (sym_te->sentry ()->isVariable () ||
+// sym_te->sentry ()->isReference ())
+// {
+// ret_yv = YCP_getset_variable (aTHX_ ns_name, sym_te->sentry (), args);
+// }
+// else
+// { // no indent yet
+//
+// Y2Function *func_call = ns->createFunctionCall (func_name, NULL);
+// if (func_call == NULL)
+// {
+// y2error ("No such function %s::%s", ns_name, func_name);
+// XSRETURN_EMPTY;
+// }
+//
+// // before we attach the parameters, we have to convert them
+// // from Ruby to YCP. That means knowing the destination type beforehand.
+// // (Later if we get overloading, this will become messy)
+//
+// // go through the actual parameters
+// unsigned j;
+// for (j = 0; j < args.size (); ++j)
+// {
+// // convert the value according to the expected type:
+//
+// constTypePtr param_tp = func_call->wantedParameterType ();
+//
+// YCPValue param_v = yperl->fromRubyScalar (args[j], param_tp);
+// if (param_v.isNull ())
+// {
+// // an error has already been reported, now refine it.
+// y2error ("... when passing parameter #%u to %s::%s",
+// j, ns_name, func_name);
+// XSRETURN_EMPTY;
+// }
+//
+// // Attach the parameter
+// bool ok = func_call->appendParameter (param_v);
+// if (!ok)
+// {
+// // TODO really need to know the place in Ruby code
+// // where we were called from.
+// XSRETURN_EMPTY;
+// }
+// } // for each actual parameter
+//
+// bool ok = func_call->finishParameters ();
+// if (!ok)
+// {
+// // TODO really need to know the place in Ruby code
+// // where we were called from.
+// XSRETURN_EMPTY;
+// }
+// // go call it now!
+// y2debug ("Ruby is calling %s::%s", ns_name, func_name);
+// ret_yv = func_call->evaluateCall ();
+// delete func_call;
+//
+// } // if not variable
+// }
+//
+// if (ret_yv.isNull ())
+// {
+// XSRETURN_EMPTY;
+// }
+//
+// y2debug ("YCP returned %s", ret_yv->toString ().c_str ());
+//
+// I32 context = GIMME_V; // what context were we called in?
+// if (context == G_VOID)
+// {
+// y2debug ("void context, returning nothing");
+// XSRETURN_EMPTY;
+// }
+// #if 0
+// // disabled to be consistent with YRuby::call - disregard array context
+// else if (context == G_ARRAY && ret_yv->isList ())
+// {
+// y2debug ("returning a list");
+// // return a list iff they want a list and we have it
+// YCPList ret_lv = ret_yv->asList ();
+// int ret_len = ret_lv->size ();
+//
+// SP -= items; // reset stack pointer (declared by dXSARGS)
+// EXTEND (SP, ret_len); // make room for the list
+// for (int i = 0; i < ret_len; ++i)
+// {
+// // put return values, no need to XPUSHs
+// PUSHs (sv_2mortal (yperl->newRubyScalar (ret_lv->value (i), false)));
+// }
+// XSRETURN (ret_len);
+// }
+// #endif
+// else
+// {
+// y2debug ("returning a scalar");
+// ST (0) = sv_2mortal (yperl->newRubyScalar (ret_yv, false));
+// XSRETURN (1);
+// }
+// }
+//
+//
+// YCPValue YCP_call_SCR (pTHX_ const char * func_name, const vector& args)
+// {
+// // access directly the statically declared builtins
+// extern StaticDeclaration static_declarations;
+// string qualified_name_s = string ("SCR::") + func_name;
+// const char *qualified_name = qualified_name_s.c_str ();
+//
+// /*
+// this does not work across namespaces
+// TableEntry *bi_te = static_declarations.symbolTable ()->find (qualified_name);
+// if (bi_te == NULL)
+// {
+// y2error ("No such builtin %s",qualified_name);
+// return YCPNull ();
+// }
+//
+// SymbolEntry *bi_se = bi_te->sentry ();
+// assert (bi_se != NULL);
+// assert (bi_se->isBuiltin ());
+// declaration_t bi_dt = bi_se->declaration ();
+// */
+// declaration_t *bi_dt = static_declarations.findDeclaration (qualified_name);
+// if (bi_dt == NULL)
+// {
+// y2error ("No such builtin '%s'", qualified_name);
+// return YCPNull ();
+// }
+//
+// // construct a builtin call using the proper overloaded builtin
+// YEBuiltin *bi_call = new YEBuiltin (bi_dt);
+//
+// // attach the parameters:
+//
+// // we would like to know the destination type so that we could
+// // convert eg a Ruby scalar to a YCP symbol, but because the
+// // builtins may be overloaded, let's say we want Any
+//
+// // maybe a special exceptional hack to make Path for the 1st argument?
+//
+// YRuby::acceptInterpreter (aTHX); // access the singleton object
+// YRuby *yperl = YRuby::yRuby (); // access the singleton object
+// // go through the actual parameters
+// unsigned j;
+// for (j = 0; j < args.size (); ++j)
+// {
+// // convert the value according to the expected type:
+// constTypePtr param_tp = (j == 0)? Type::Path : Type::Any;
+//
+// YCPValue param_v = yperl->fromRubyScalar (args[j], param_tp);
+// if (param_v.isNull ())
+// {
+// // an error has already been reported, now refine it.
+// // Can't know parameter name?
+// y2error ("... when passing parameter #%u to builtin %s",
+// j, qualified_name);
+// return YCPNull ();
+// }
+// // Such YConsts without a specific type produce invalid
+// // bytecode. (Which is OK here)
+// // The actual parameter's YCode becomes owned by the function call?
+// YConst *param_c = new YConst (YCode::ycConstant, param_v);
+// // for attaching the parameter, must get the real type so that it matches
+// constTypePtr act_param_tp = Type::vt2type (param_v->valuetype ());
+// // Attach the parameter
+// // Returns NULL if OK, Type::Error if excessive argument
+// // Other errors (bad code, bad type) shouldn't happen
+// constTypePtr err_tp = bi_call->attachParameter (param_c, act_param_tp);
+// if (err_tp != NULL)
+// {
+// if (err_tp->isError ())
+// {
+// // TODO really need to know the place in Ruby code
+// // where we were called from.
+// y2error ("Excessive parameter to builtin %s",
+// qualified_name);
+// }
+// else
+// {
+// y2internal ("attachParameter returned %s",
+// err_tp->toString ().c_str ());
+// }
+// return YCPNull ();
+// }
+// } // for each actual parameter
+//
+// // now must check if we got fewer parameters than needed
+// // or there was another error while resolving the overload
+// constTypePtr err_tp = bi_call->finalize (RubyLogger::instance ());
+// if (err_tp != NULL)
+// {
+// // apparently the error was already reported?
+// y2error ("Error type %s when finalizing builtin %s",
+// err_tp->toString ().c_str (), qualified_name);
+// return YCPNull ();
+// }
+//
+// // go call it now!
+// y2debug ("Ruby is calling builtin %s", qualified_name);
+// YCPValue ret_yv = bi_call->evaluate (false /* no const subexpr elim */);
+// delete bi_call;
+//
+// return ret_yv;
+// }
+//
+// /*
+// * If we got no arguments, return the variable value.
+// * If we got one argument, set the variable value (return YCPVoid).
+// * Otherwise error (and return YCPNull)
+// * ns_name is for error reporting
+// */
+// YCPValue YCP_getset_variable (pTHX_ const char * ns_name, SymbolEntryPtr var_se, const vector& args)
+// {
+// YCPValue ret_yv = YCPNull ();
+// unsigned n = args.size ();
+// // first two args are the namespace and variable name
+// if (n == 0)
+// {
+// // get
+// ret_yv = var_se->value ();
+// }
+// else if (n == 1)
+// {
+// // set
+// YRuby::acceptInterpreter (aTHX); // access the singleton object
+// YRuby *yperl = YRuby::yRuby (); // access the singleton object
+// YCPValue val_yv = yperl->fromRubyScalar (args[0], var_se->type ());
+// if (val_yv.isNull ())
+// {
+// // an error has already been reported, now refine it.
+// y2error ("... when setting value of %s::%s",
+// ns_name, var_se->name ());
+// return YCPNull ();
+// }
+// ret_yv = var_se->setValue (val_yv);
+// }
+// else
+// {
+// y2error ("Variable %s: don't know what to do, %u arguments",
+// var_se->name (), n);
+// }
+// return ret_yv;
+// }
+//
+// // XS_YCP_close_ui is called in END to close the ncurses window
+// // if the ui was created in Ruby
+// Y2Component *owned_uic = 0;
+// Y2Component *owned_wfmc = 0;
+//
+// // creates a ui component, if not already there, and returns the name
+// // of the one that will be used
+// XS(XS_YCP_init_ui); /* prototype to pass -Wmissing-prototypes */
+// XS(XS_YCP_init_ui)
+// {
+// dXSARGS;
+//
+// const char *ui_name = "ncurses";
+//
+// if (items == 1)
+// {
+// ui_name = SvPV_nolen (ST (0));
+// }
+// else if (items != 0)
+// {
+// y2error ("Zero or one arguments required (ui name, default %s", ui_name);
+// XSRETURN_EMPTY;
+// }
+//
+// Y2Component *c = YUIComponent::uiComponent ();
+// if (c == 0)
+// {
+// y2debug ("UI component not created yet, creating %s", ui_name);
+//
+// c = Y2ComponentBroker::createServer (ui_name);
+// if (c == 0)
+// {
+// y2error ("Cannot create component %s", ui_name);
+// XSRETURN_EMPTY;
+// }
+//
+// if (YUIComponent::uiComponent () == 0)
+// {
+// y2error ("Component %s is not a UI", ui_name);
+// XSRETURN_EMPTY;
+// }
+// else
+// {
+// // got it - initialize, remember
+// c->setServerOptions (0, NULL);
+// owned_uic = c;
+// }
+// }
+// else
+// {
+// y2debug ("UI component already present: %s", c->name ().c_str ());
+// }
+//
+// ST (0) = sv_2mortal (newSVpv (c->name ().c_str (), 0));
+// XSRETURN (1);
+// }
+
+void init_wfm ()
+{
+ if (Y2WFMComponent::instance () == 0)
+ {
+ owned_wfmc = Y2ComponentBroker::createClient ("wfm");
+ if (owned_wfmc == 0)
+ {
+ y2error ("Cannot create WFM component");
+ }
+ }
+}
+
+// XS(XS_YCP_close_components); /* prototype to pass -Wmissing-prototypes */
+// XS(XS_YCP_close_components)
+// {
+// dXSARGS;
+// // get rid of warning: unused variable `I32 items'
+// I32 __attribute__ ((unused)) foo = items;
+//
+// if (owned_uic != 0)
+// {
+// delete owned_uic;
+// owned_uic = 0;
+// }
+//
+// if (owned_wfmc != 0)
+// {
+// delete owned_wfmc;
+// owned_wfmc = 0;
+// }
+//
+// XSRETURN_YES;
+// }
+//
+// /* called by XSLoader::load ('YaST::YCP') */
+// #ifdef __cplusplus
+// extern "C"
+// #endif
+// XS(boot_YaST__YCP); /* prototype to pass -Wmissing-prototypes */
+// XS(boot_YaST__YCP)
+// {
+// dXSARGS;
+// // get rid of warning: unused variable `I32 items'
+// I32 __attribute__ ((unused)) foo = items;
+// char* file = __FILE__;
+//
+// XS_VERSION_BOOTCHECK ;
+//
+// init_wfm ();
+//
+// newXS("YaST::YCP::call_ycp", XS_YCP_call_ycp, file);
+// newXS("YaST::YCP::close_components", XS_YCP_close_components, file);
+// newXS("YaST::YCP::init_ui", XS_YCP_init_ui, file);
+// newXS("YaST::YCP::y2_logger", XS_YCP_y2_logger, file);
+// XSRETURN_YES;
+// }
Added: branches/tmp/dmacvicar/ruby-yast/src/ruby/YCP.rb
URL: http://svn.opensuse.org/viewcvs/yast/branches/tmp/dmacvicar/ruby-yast/src/ruby/YCP.rb?rev=39021&view=auto
==============================================================================
--- branches/tmp/dmacvicar/ruby-yast/src/ruby/YCP.rb (added)
+++ branches/tmp/dmacvicar/ruby-yast/src/ruby/YCP.rb Mon Jun 25 18:26:33 2007
@@ -0,0 +1,520 @@
+#! /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
+LYaST::SCRAgent|YaST::SCRAgent and L, 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
+LYaST::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