Refactor Arch - don't expose full C++ API
authorKlaus Kämpf <kkaempf@suse.de>
Sun, 7 Nov 2010 20:52:27 +0000 (21:52 +0100)
committerKlaus Kämpf <kkaempf@suse.de>
Sun, 7 Nov 2010 20:52:27 +0000 (21:52 +0100)
Completely hide the full C++ API for the 'Arch' class from SWIG.

Instead only expose some functions in a way thats useful for the
target language.

Add Ruby and Python tests.

swig/Arch.i
swig/python/tests/arch.py [new file with mode: 0644]
swig/ruby/tests/arch.rb
swig/zypp.i

index 417ecdf..0675ad9 100644 (file)
-// Ignore static versions shadowed by member functions
-%ignore zypp::Arch::compare(const Arch &, const Arch &);
-%ignore zypp::Arch::asString( const CompatSet & cset );
+/*
+ * Arch.i
+ *
+ * Architecture definitions
+ *
+ */
 
-template<class A, class B> class std::unary_function {};
-%template(ArchCompatFun) std::unary_function<zypp::Arch, bool>;
-
-%include <zypp/Arch.h>
+%nodefault zypp::Arch;
+namespace zypp {
+class Arch {
+};
+};
 
 %extend zypp::Arch
 {
+  Arch(const char *s) {
+    return new zypp::Arch(s);
+  }
+  ~Arch() {
+    delete $self;
+  }
+#if defined(SWIGRUBY)
+%typemap(out) int is_builtin
+   "$result = $1 ? Qtrue : Qfalse;";
+#endif
+  /*
+   * Whether this is a builtin (or known) architecture.
+   *
+   */
+  int is_builtin() {
+    return ($self->isBuiltIn() ? 1 : 0);
+  }
+#if defined(SWIGRUBY)
+%typemap(out) int compatible_with
+   "$result = $1 ? Qtrue : Qfalse;";
+#endif
+  /*
+   * Check if this architecture is compatible with another one
+   *
+   * e.g. 'noarch' is compatible with any arch
+   *
+   */
+  int compatible_with(const zypp::Arch & arch) {
+    return ($self->compatibleWith(arch) ? 1 : 0);
+  }
+
+  /*
+   * return the arch before noarch if it's not a multilib arch
+   * (e.g. x86_64,sparc64v,sparc64,ppc64,s390x).
+   *
+   */
+  zypp::Arch base_arch()
+  {
+    return $self->baseArch();
+  }
+
+#if defined(SWIGRUBY)
+%alias compare "<=>";
+#endif
+#if defined(SWIGPYTHON)
+  /*
+   * :nodoc:
+   */
+  int __cmp__( const zypp::Arch & arch )
+#else
+  /*
+   * Comparison operator
+   *
+   * returning <0 (smaller), 0 (equal) or >0 (greater)
+   *
+   */
+  int compare( const zypp::Arch & arch )
+#endif
+  {  return $self->compare( arch ); }
+
+#if defined(SWIGPERL)
+  /*
+   * :nodoc:
+   */
+  int __eq__( const zypp::Arch & arch )
+#endif
+#if defined(SWIGRUBY)
+%typemap(out) int equal
+   "$result = $1 ? Qtrue : Qfalse;";
+%rename("==") equal;
+  /*
+   * Equality operator
+   *
+   */
+  int equal( const zypp::Arch & arch )
+#endif
+    
+#if defined(SWIGPYTHON)
+  /*
+   * :nodoc:
+   * Python treats 'eq' and 'ne' distinct.
+   */
+  int __ne__( const zypp::Arch & arch )
+  { return $self->compare(arch) != 0; }
+  int __eq__( const zypp::Arch & arch )
+#endif
+  { return $self->compare(arch) == 0; }
+    
+
 #ifdef SWIGPYTHON
 %rename ("__str__") string();
 #endif
 #ifdef SWIGRUBY
 %rename ("to_s") string();
 #endif
-
-  std::string string() const
+  /*
+   * String representation
+   *
+   */
+  const char *string()
   {
-    std::ostringstream str;
-    str << *self;
-    return str.str();
+    return $self->c_str();
   }
 }
diff --git a/swig/python/tests/arch.py b/swig/python/tests/arch.py
new file mode 100644 (file)
index 0000000..01751b0
--- /dev/null
@@ -0,0 +1,32 @@
+#
+# Arch
+#
+import unittest
+
+import sys
+sys.path.insert(0, '../../../build/swig/python')
+from zypp import Arch
+
+class TestSequenceFunctions(unittest.TestCase):
+    
+  def testarch(self):
+    a = Arch("i386")
+    assert a
+    assert "i386" == a.__str__()
+    assert a.is_builtin()
+    
+    b = Arch("i486")
+    assert b
+    assert "i486" == b.__str__()
+    assert b.is_builtin()
+    assert a == b.base_arch()
+    assert a < b
+    assert a.compatible_with(b)
+
+    z = Arch("xyzzy")
+    assert z
+    assert "xyzzy" == z.__str__()
+    assert not z.is_builtin()
+
+if __name__ == '__main__':
+  unittest.main()
index 3677afb..95d3cef 100644 (file)
@@ -1,18 +1,35 @@
 #
-# Example for Arch
+# Arch
 #
 
 $:.unshift "../../../build/swig/ruby"
 
 require 'test/unit'
+require 'zypp'
 
-class LoadTest < Test::Unit::TestCase
-  require 'zypp'
+class Zypp::Arch
+  include Comparable
+end
+
+class ArchTest < Test::Unit::TestCase
   include Zypp
   def test_arch
     a = Arch.new("i386")
     assert a
-    puts a.to_s
-#    assert a.to_s == "i386"
+    assert_equal "i386", a.to_s
+    assert a.is_builtin
+    
+    b = Arch.new("i486")
+    assert b
+    assert_equal "i486", b.to_s
+    assert b.is_builtin
+    assert_equal a, b.base_arch
+    assert a < b
+    assert a.compatible_with(b)
+
+    z = Arch.new("xyzzy")
+    assert z
+    assert_equal "xyzzy", z.to_s
+    assert !z.is_builtin
   end
 end
index a9323d3..dc0cd2e 100644 (file)
@@ -169,7 +169,6 @@ namespace zypp {
 %include "std_string.i"
 %include "stl.i"
 
-
 #ifdef SWIGRUBY
 %include "ruby/std_list.i"
 %include "ruby/std_set.i"
@@ -187,6 +186,9 @@ namespace zypp {
 %include "perl5/perl.i"
 #endif
 
+/* These include files are already cleaned up from C++ cruft */
+%include "Arch.i"
+
 #ifdef BOOST_SMARTPTR_INCLUDE_DIR
 %import <boost/smart_ptr/scoped_ptr.hpp>
 %import <boost/smart_ptr/shared_ptr.hpp>
@@ -201,12 +203,12 @@ namespace zypp {
 %import <zypp/base/PtrTypes.h>
 %import <zypp/base/Flags.h>
 
+#if 1 /* set 0 for testing, these files still carry the full C++ cruft */
 %include "IdStringType.i"
 %include "Pathname.i"
 %include "ByteCount.i"
 %include "Url.i"
 %include "NeedAType.i"
-%include "Arch.i"
 %include "Edition.i"
 %include "Kind.i"
 %include "CheckSum.i"
@@ -242,6 +244,7 @@ namespace zypp {
 %include "Resolver.i"
 %include "ZConfig.i"
 %include "Callbacks.i"
+#endif
 
 %ignore zypp::ZYpp::setTextLocale;
 %ignore zypp::ZYpp::getTextLocale;