summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKlaus Kämpf <kkaempf@suse.de>2010-11-06 22:11:06 +0100
committerKlaus Kämpf <kkaempf@suse.de>2010-11-06 22:11:06 +0100
commite5a53c804d294b76cc529f28efca16ad52d07fd9 (patch)
tree04ecb93b5f74b01fde8d2a73e08f86ee6177a312
parent78111f8aa14af7693e771897c65f286f858330bf (diff)
downloadlibzypp-bindings-e5a53c804d294b76cc529f28efca16ad52d07fd9.tar.gz
libzypp-bindings-e5a53c804d294b76cc529f28efca16ad52d07fd9.tar.bz2
libzypp-bindings-e5a53c804d294b76cc529f28efca16ad52d07fd9.zip
Initial step towards callbacks support
This commit introduces generic (all target languages) support for callbacks. Callbacks are sent to a 'callback object instance' which must be instantiated. Currently implemented are commit callbacks, requiring an instance of 'CommitCallbacks' ** this is work in progress ** Next: Provide example code and tests for Python and Ruby
-rw-r--r--swig/Callbacks.i192
-rw-r--r--swig/CommitCallbacks.h33
-rw-r--r--swig/perl5/CMakeLists.txt1
-rw-r--r--swig/python/CMakeLists.txt1
-rw-r--r--swig/ruby/CMakeLists.txt1
-rw-r--r--swig/zypp.i92
6 files changed, 317 insertions, 3 deletions
diff --git a/swig/Callbacks.i b/swig/Callbacks.i
new file mode 100644
index 0000000..016fdc4
--- /dev/null
+++ b/swig/Callbacks.i
@@ -0,0 +1,192 @@
+/*
+ * Callbacks.i
+ *
+ * Callback glue code
+ *
+ * Author: Klaus Kaempf <kkaempf@suse.de>
+ *
+ */
+
+
+/*
+ * Commit callbacks
+ *
+ */
+
+%{
+
+/*
+ * Patch message
+ *
+ */
+
+struct PatchMessageReportReceiver : public zypp::callback::ReceiveReport<zypp::target::PatchMessageReport>
+{
+
+ private:
+ Target_Type _instance;
+ public:
+ PatchMessageReportReceiver(Target_Type instance) { _instance = instance; }
+ /** Display \c patch->message().
+ * Return \c true to continue, \c false to abort commit.
+ */
+ virtual bool show( zypp::Patch::constPtr & patch )
+ {
+ return true;
+ }
+};
+
+
+/*
+ * Patch script
+ *
+ */
+
+struct PatchScriptReportReceiver : public zypp::callback::ReceiveReport<zypp::target::PatchScriptReport>
+{
+
+ private:
+ Target_Type _instance;
+ public:
+ PatchScriptReportReceiver(Target_Type instance) { _instance = instance; }
+
+ virtual void start( const zypp::Package::constPtr & package,
+ const zypp::Pathname & path_r ) // script path
+ {
+ }
+
+ /**
+ * Progress provides the script output. If the script is quiet,
+ * from time to time still-alive pings are sent to the ui. (Notify=PING)
+ * Returning \c FALSE aborts script execution.
+ */
+ virtual bool progress( Notify kind, const std::string &output )
+ {
+ return true;
+ }
+
+ /** Report error. */
+ virtual Action problem( const std::string & description )
+ {
+ return zypp::target::PatchScriptReport::ABORT;
+ }
+
+ /** Report success. */
+ virtual void finish()
+ {
+ }
+};
+
+
+/*
+ * Remove
+ *
+ */
+
+struct RemoveResolvableReportReceiver : public zypp::callback::ReceiveReport<zypp::target::rpm::RemoveResolvableReport>
+{
+
+ private:
+ Target_Type _instance;
+ public:
+ RemoveResolvableReportReceiver(Target_Type instance) { _instance = instance; }
+
+ virtual void start( zypp::Resolvable::constPtr resolvable )
+ {
+ Target_Type r = SWIG_NewPointerObj((void *)&(*resolvable), SWIGTYPE_p_zypp__Resolvable, 0);
+#if defined(SWIGPYTHON)
+ PyObject *pyfunc = PyObject_GetAttrString(_instance, "removal_start");
+ PyObject *prv = NULL;
+
+ if (pyfunc == NULL)
+ {
+ PyErr_Print();
+ PyErr_Clear();
+ goto cleanup;
+ }
+ if (! PyCallable_Check(pyfunc))
+ {
+ goto cleanup;
+ }
+
+ prv = PyObject_CallObject(pyfunc, r);
+ if (PyErr_Occurred())
+ {
+ PyErr_Clear();
+ goto cleanup;
+ }
+
+cleanup:
+ if (pyfunc) Py_DecRef(pyfunc);
+ if (prv) Py_DecRef(prv);
+#endif
+
+#if defined(SWIGRUBY)
+#if SWIG_VERSION < 0x010340
+#define COMMIT_CLASS cTransport
+#else
+#define COMMIT_CLASS SwigClassTransport
+#endif
+ VALUE result = rb_funcall( _instance, rb_intern("removal_start" ), 1, r );
+#endif
+
+ return;
+ }
+
+ virtual bool progress(int value, zypp::Resolvable::constPtr resolvable)
+ {
+ return true;
+ }
+
+ virtual Action problem( zypp::Resolvable::constPtr resolvable, Error error, const std::string & description )
+ {
+ return RemoveResolvableReportReceiver::ABORT;
+ }
+
+ virtual void finish( zypp::Resolvable::constPtr resolvable, Error error, const std::string & reason )
+ {
+ }
+};
+
+
+/*
+ * Install
+ *
+ */
+
+struct InstallResolvableReportReceiver : public zypp::callback::ReceiveReport<zypp::target::rpm::InstallResolvableReport>
+{
+
+ private:
+ Target_Type _instance;
+ public:
+ InstallResolvableReportReceiver(Target_Type instance) { _instance = instance; }
+
+ void display_step( zypp::Resolvable::constPtr resolvable, int value )
+ {
+ }
+
+ virtual void start( zypp::Resolvable::constPtr resolvable )
+ {
+ }
+
+ virtual bool progress(int value, zypp::Resolvable::constPtr resolvable)
+ {
+ return true;
+ }
+
+ virtual Action problem( zypp::Resolvable::constPtr resolvable, Error error, const std::string & description, RpmLevel level )
+ {
+ return ABORT;
+ }
+
+ virtual void finish( zypp::Resolvable::constPtr resolvable, Error error, const std::string & reason, RpmLevel level )
+ {
+ }
+};
+
+#include "CommitCallbacks.h"
+
+%}
+
+%include "CommitCallbacks.h"
diff --git a/swig/CommitCallbacks.h b/swig/CommitCallbacks.h
new file mode 100644
index 0000000..e02cb73
--- /dev/null
+++ b/swig/CommitCallbacks.h
@@ -0,0 +1,33 @@
+class CommitCallbacks {
+
+ private:
+ PatchMessageReportReceiver _messageReceiver;
+ PatchScriptReportReceiver _scriptReceiver;
+ RemoveResolvableReportReceiver _installReceiver;
+ InstallResolvableReportReceiver _removeReceiver;
+
+ Target_Type _instance;
+ public:
+ CommitCallbacks(Target_Type instance)
+ : _messageReceiver(instance)
+ , _scriptReceiver(instance)
+ , _installReceiver(instance)
+ , _removeReceiver(instance)
+ {
+ _instance = instance;
+ Target_INCREF(_instance);
+ _messageReceiver.connect();
+ _scriptReceiver.connect();
+ _installReceiver.connect();
+ _removeReceiver.connect();
+ }
+
+ ~CommitCallbacks()
+ {
+ _removeReceiver.disconnect();
+ _installReceiver.disconnect();
+ _scriptReceiver.disconnect();
+ _messageReceiver.disconnect();
+ Target_DECREF(_instance);
+ }
+};
diff --git a/swig/perl5/CMakeLists.txt b/swig/perl5/CMakeLists.txt
index 80c4420..7c16b9d 100644
--- a/swig/perl5/CMakeLists.txt
+++ b/swig/perl5/CMakeLists.txt
@@ -46,6 +46,7 @@ SET_TARGET_PROPERTIES( zypp_perl
)
INCLUDE_DIRECTORIES( ${PERL_CORE_DIR} )
+INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/swig )
INCLUDE_DIRECTORIES( ${ZYPP_INCLUDE_DIR} )
TARGET_LINK_LIBRARIES( zypp_perl ${ZYPP_LIBRARY} )
diff --git a/swig/python/CMakeLists.txt b/swig/python/CMakeLists.txt
index 2542f5a..8aab73b 100644
--- a/swig/python/CMakeLists.txt
+++ b/swig/python/CMakeLists.txt
@@ -40,6 +40,7 @@ SET_TARGET_PROPERTIES( zypp_python
)
INCLUDE_DIRECTORIES( ${PYTHON_INCLUDE_PATH} )
+INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/swig )
INCLUDE_DIRECTORIES( ${ZYPP_INCLUDE_DIR} )
TARGET_LINK_LIBRARIES( zypp_python ${ZYPP_LIBRARY} )
diff --git a/swig/ruby/CMakeLists.txt b/swig/ruby/CMakeLists.txt
index 41c7efd..2a7730a 100644
--- a/swig/ruby/CMakeLists.txt
+++ b/swig/ruby/CMakeLists.txt
@@ -29,6 +29,7 @@ ADD_LIBRARY( zypp_ruby SHARED ${SWIG_OUTPUT} )
SET_TARGET_PROPERTIES( zypp_ruby PROPERTIES OUTPUT_NAME "zypp" PREFIX "" )
INCLUDE_DIRECTORIES( ${RUBY_INCLUDE_PATH} )
+INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/swig )
INCLUDE_DIRECTORIES( ${ZYPP_INCLUDE_DIR} )
TARGET_LINK_LIBRARIES( zypp_ruby ${RUBY_LIBRARY} )
diff --git a/swig/zypp.i b/swig/zypp.i
index d005d51..7dd31e6 100644
--- a/swig/zypp.i
+++ b/swig/zypp.i
@@ -19,6 +19,93 @@
#define REG_NOSUB (REG_NEWLINE << 1)
#endif
+/*
+ * type definitions to keep the C code generic
+ */
+
+#if defined(SWIGPYTHON)
+#define Target_Null_p(x) (x == Py_None)
+#define Target_INCREF(x) Py_INCREF(x)
+#define Target_DECREF(x) Py_DECREF(x)
+#define Target_True Py_True
+#define Target_False Py_False
+#define Target_Null NULL
+#define Target_Void Py_None
+#define Target_Type PyObject*
+#define Target_Bool(x) PyBool_FromLong(x)
+#define Target_WChar(x) PyInt_FromLong(x)
+#define Target_Int(x) PyInt_FromLong(x)
+#define Target_String(x) PyString_FromString(x)
+#define Target_Real(x) Py_None
+#define Target_Array() PyList_New(0)
+#define Target_SizedArray(len) PyList_New(len)
+#define Target_Append(x,y) PyList_Append(x,y)
+#define Target_DateTime(x) Py_None
+#include <Python.h>
+#define TARGET_THREAD_BEGIN_BLOCK SWIG_PYTHON_THREAD_BEGIN_BLOCK
+#define TARGET_THREAD_END_BLOCK SWIG_PYTHON_THREAD_END_BLOCK
+#define TARGET_THREAD_BEGIN_ALLOW SWIG_PYTHON_THREAD_BEGIN_ALLOW
+#define TARGET_THREAD_END_ALLOW SWIG_PYTHON_THREAD_END_ALLOW
+#endif
+
+#if defined(SWIGRUBY)
+#define Target_Null_p(x) NIL_P(x)
+#define Target_INCREF(x)
+#define Target_DECREF(x)
+#define Target_True Qtrue
+#define Target_False Qfalse
+#define Target_Null Qnil
+#define Target_Void Qnil
+#define Target_Type VALUE
+#define Target_Bool(x) ((x)?Qtrue:Qfalse)
+#define Target_WChar(x) INT2FIX(x)
+#define Target_Int(x) INT2FIX(x)
+#define Target_String(x) rb_str_new2(x)
+#define Target_Real(x) rb_float_new(x)
+#define Target_Array() rb_ary_new()
+#define Target_SizedArray(len) rb_ary_new2(len)
+#define Target_Append(x,y) rb_ary_push(x,y)
+#define Target_DateTime(x) Qnil
+#define TARGET_THREAD_BEGIN_BLOCK do {} while(0)
+#define TARGET_THREAD_END_BLOCK do {} while(0)
+#define TARGET_THREAD_BEGIN_ALLOW do {} while(0)
+#define TARGET_THREAD_END_ALLOW do {} while(0)
+#include <ruby.h>
+#include <rubyio.h>
+#endif
+
+#if defined(SWIGPERL)
+#define TARGET_THREAD_BEGIN_BLOCK do {} while(0)
+#define TARGET_THREAD_END_BLOCK do {} while(0)
+#define TARGET_THREAD_BEGIN_ALLOW do {} while(0)
+#define TARGET_THREAD_END_ALLOW do {} while(0)
+
+SWIGINTERNINLINE SV *SWIG_From_long SWIG_PERL_DECL_ARGS_1(long value);
+SWIGINTERNINLINE SV *SWIG_FromCharPtr(const char *cptr);
+SWIGINTERNINLINE SV *SWIG_From_double SWIG_PERL_DECL_ARGS_1(double value);
+
+#define Target_Null_p(x) (x == NULL)
+#define Target_INCREF(x)
+#define Target_DECREF(x)
+#define Target_True (&PL_sv_yes)
+#define Target_False (&PL_sv_no)
+#define Target_Null NULL
+#define Target_Void NULL
+#define Target_Type SV *
+#define Target_Bool(x) (x)?Target_True:Target_False
+#define Target_WChar(x) NULL
+#define Target_Int(x) SWIG_From_long(x)
+#define Target_String(x) SWIG_FromCharPtr(x)
+#define Target_Real(x) SWIG_From_double(x)
+#define Target_Array() (SV *)newAV()
+#define Target_SizedArray(len) (SV *)newAV()
+#define Target_Append(x,y) av_push(((AV *)(x)), y)
+#define Target_DateTime(x) NULL
+#include <perl.h>
+#include <EXTERN.h>
+#endif
+
+
#include <sstream>
#include "zypp/base/PtrTypes.h"
#include "zypp/base/ReferenceCounted.h"
@@ -51,6 +138,7 @@ using namespace zypp::resfilter;
using namespace zypp::filesystem;
typedef std::list<std::string> StringList;
+
%}
%nodefault ByKind;
@@ -143,9 +231,7 @@ namespace zypp {
%include "TmpPath.i"
%include "Resolver.i"
%include "ZConfig.i"
-#ifdef SWIGPYTHON
-%include "python/callbacks.i"
-#endif
+%include "Callbacks.i"
%ignore zypp::ZYpp::setTextLocale;
%ignore zypp::ZYpp::getTextLocale;