Mailinglist Archive: yast-commit (535 mails)

< Previous Next >
[yast-commit] r41338 - in /trunk/python-bindings/src: Makefile.am YCPDeclarations.cc YCPDeclarations.h YCPDeclarations.py
  • From: dfiser@xxxxxxxxxxxxxxxx
  • Date: Wed, 10 Oct 2007 14:52:28 -0000
  • Message-id: <20071010145228.991ED35ED2@xxxxxxxxxxxxxxxx>
Author: dfiser
Date: Wed Oct 10 16:52:28 2007
New Revision: 41338

URL: http://svn.opensuse.org/viewcvs/yast?rev=41338&view=rev
Log:
 - Added YCPDeclarations tool, i.e. YCPDeclarations.py - python module,
   YCPDeclarations.h and .cc - c++ interface to access declarations
   declared using YCPDeclarations.py module.


Added:
    trunk/python-bindings/src/YCPDeclarations.cc
    trunk/python-bindings/src/YCPDeclarations.h
    trunk/python-bindings/src/YCPDeclarations.py
Modified:
    trunk/python-bindings/src/Makefile.am

Modified: trunk/python-bindings/src/Makefile.am
URL: http://svn.opensuse.org/viewcvs/yast/trunk/python-bindings/src/Makefile.am?rev=41338&r1=41337&r2=41338&view=diff
==============================================================================
--- trunk/python-bindings/src/Makefile.am (original)
+++ trunk/python-bindings/src/Makefile.am Wed Oct 10 16:52:28 2007
@@ -5,15 +5,16 @@
 AM_CXXFLAGS = -DY2LOG=\"Python\" -DMODULEDIR=\"$(moduledir)\"
 
 MY_PYTHON_VENDORARCH = $(subst /usr,$(prefix),$(PYTHON_VENDORARCH))
-pythonpydir = $(MY_PYTHON_VENDORARCH)/YaST
+#pythonpydir = $(MY_PYTHON_VENDORARCH)/YaST
+pythonpydir = $(MY_PYTHON_VENDORARCH)/site-packages
 pythonsodir = $(MY_PYTHON_VENDORARCH)/site-packages
 
 
-#pythonpm_DATA = YCP.pm
+pythonpy_DATA = YCPDeclarations.py
 
 # plugin, libtool forces 'lib' prefix
 plugin_LTLIBRARIES = libpy2lang_python.la
-noinst_LTLIBRARIES = libYCPTypes.la liby2lang_python.la
+noinst_LTLIBRARIES = libYCPTypes.la liby2lang_python.la libYCPDeclarations.la
 pythonso_LTLIBRARIES = libYCP.la
 
 libYCPTypes_la_SOURCES = YCPTypes.cc YCPTypes.h \
@@ -22,6 +23,8 @@
                          YCPTypes/Symbol.cc \
                          YCPTypes/Term.cc
 
+libYCPDeclarations_la_SOURCES = YCPDeclarations.cc YCPDeclarations.h
+
 # binary part of the python module
 libYCP_la_SOURCES =                            \
        $(liby2lang_python_la_SOURCES)          \
@@ -49,7 +52,7 @@
                -ly2util                        \
                -version-info 2:0
 
-libYCP_la_LIBADD = libYCPTypes.la
+libYCP_la_LIBADD = libYCPTypes.la #libYCPDeclarations.la
 
 
 libpy2lang_python_la_LDFLAGS = -version-info 2:0
@@ -62,7 +65,7 @@
                -L$(libdir) -L$(plugindir)      \
                -lycp -ly2 -ly2util
 
-libpy2lang_python_la_LIBADD = libYCPTypes.la
+libpy2lang_python_la_LIBADD = libYCPTypes.la libYCPDeclarations.la
 
 
 liby2lang_python_la_LIBADD  = $(PYTHON_LDFLAGS)
@@ -105,3 +108,5 @@
 # nodist_module_DATA = YaPI.pm
 
 #EXTRA_DIST = $(pythonpy_DATA) $(module_DATA)
+EXTRA_DIST = $(pythonpy_DATA)
+

Added: trunk/python-bindings/src/YCPDeclarations.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/python-bindings/src/YCPDeclarations.cc?rev=41338&view=auto
==============================================================================
--- trunk/python-bindings/src/YCPDeclarations.cc (added)
+++ trunk/python-bindings/src/YCPDeclarations.cc Wed Oct 10 16:52:28 2007
@@ -0,0 +1,219 @@
+#include "YCPDeclarations.h"
+#include <iostream>
+using std::string;
+using std::vector;
+//#define DBG(str) \
+    std::cerr << __FILE__ << ": " << __LINE__ << ": " << str << std::endl; \
+    std::cerr.flush()
+#define DBG(str)
+
+
+/********** STATIC MEMBERS **********/
+std::auto_ptr<YCPDeclarations> YCPDeclarations::_instance;
+YCPDeclarations *YCPDeclarations::instance()
+{
+    if (_instance.get() == 0){
+        _instance = std::auto_ptr<YCPDeclarations>(new YCPDeclarations());
+    }
+    return _instance.get();
+}
+/********** STATIC MEMBERS END **********/
+
+
+
+
+/********** PRIVATE **********/
+bool YCPDeclarations::_isInCache(PyFunctionObject *func) const
+{
+    int len = _cache.size();
+    for (int i=0; i < len; i++){
+        if (_cache[i]->function == func)
+            return true;
+    }
+
+    return false;
+}
+
+void YCPDeclarations::_cacheFunction(PyFunctionObject *func)
+{
+    PyObject *item;
+    PyObject *params;
+    PyObject *return_type;
+    PyObject *tmp;
+    cache_function_t *function;
+    Py_ssize_t tuple_size;
+
+    DBG("Called _cacheFunction(" << (long)func << ")");
+
+    if (_isInCache(func)){
+        DBG("YCPDeclarations::_cacheFunction(" << (long)func << ") - is in cache");
+        return;
+    }
+
+    item = _getItemFromFunctionMap((PyObject *)func);
+    if (item == NULL || !PyDict_Check(item)){
+        DBG("YCPDeclarations::_cacheFunction(" << (long)func << ") - " << "error in item: " << (long)item);
+        return;
+    }
+
+    return_type = PyDict_GetItemString(item, "return_type");
+    if (return_type == NULL || !PyString_Check(return_type)){
+        DBG("YCPDeclarations::_cacheFunction(" << (long)func << ") - " << "error in return_type: " << (long)return_type);
+        return;
+    }
+    params = PyDict_GetItemString(item, "parameters");
+    if (params == NULL || !PyTuple_Check(params)){
+        DBG("YCPDeclarations::_cacheFunction(" << (long)func << ") - " << "error in params: " << (long)params);
+        return;
+    }
+
+    //allocate memory
+    function = new cache_function_t;
+
+    //function
+    function->function = func;
+
+    //return type:
+    function->return_type = _interpretType(PyString_AsString(return_type));
+
+    //parameters:
+    tuple_size = PyTuple_Size(params);
+    for (Py_ssize_t i=0; i < tuple_size; i++){
+        tmp = PyTuple_GetItem(params, i);
+        function->parameters.push_back(_interpretType(PyString_AsString(tmp)));
+    }
+
+    //add new function item
+    _cache.push_back(function);
+    DBG("_cacheFunction(" << (long)func << ") - _cache.size() : " << _cache.size());
+}
+
+const YCPDeclarations::cache_function_t *YCPDeclarations::_getCachedFunction(PyFunctionObject *func) const
+{
+    cache_function_t *ret = NULL;
+    int len = _cache.size();
+
+    DBG("");
+    DBG("_getCachedFunction(" << (long)func << ") - " << "start searching");
+    for (int i=0; i < len; i++){
+        DBG("== " << "_cache[" << i << "]->function: " << (long)_cache[i]->function);
+        if (_cache[i]->function == func){
+            ret = _cache[i];
+            break;
+        }
+    }
+
+    DBG("_getCachedFunction(" << (long)func << ") -> " << (long)ret);
+    DBG("");
+    return ret;
+}
+
+
+PyObject *YCPDeclarations::_getItemFromFunctionMap(PyObject *key)
+{
+    PyObject *dict = PyModule_GetDict(_py_self);
+    PyObject *func_map = PyDict_GetItemString(dict, "_function_map");
+
+    if (!PyDict_Check(func_map)){
+        return NULL;
+    }
+    DBG("_function_map : " << (long)func_map);
+
+    return PyDict_GetItem(func_map, key);
+}
+
+
+constTypePtr YCPDeclarations::_interpretType(const char *c_type) const
+{
+    string type(c_type);
+
+    if (type == "void")
+        return Type::Void;
+    if (type == "boolean")
+        return Type::Boolean;
+    if (type == "float")
+        return Type::Float;
+    if (type == "integer")
+        return Type::Integer;
+    if (type == "path")
+        return Type::Path;
+    if (type == "string")
+        return Type::String;
+    if (type == "symbol")
+        return Type::Symbol;
+    if (type == "term")
+        return Type::Term;
+
+    // default:
+    return Type::Any;
+}
+/********** PRIVATE END **********/
+
+
+
+
+/********** PUBLIC **********/
+
+YCPDeclarations::YCPDeclarations()
+{
+    DBG("YCPDeclarations - constructor");
+    _py_self = PyImport_ImportModule("YCPDeclarations");
+}
+
+YCPDeclarations::~YCPDeclarations()
+{
+    DBG("YCPDeclarations - destructor");
+
+    int cache_len = _cache.size();
+    for (int i=0; i < cache_len; i++){
+        delete _cache[i];
+    }
+
+    if (_py_self != NULL)
+        Py_DECREF(_py_self);
+}
+
+
+
+int YCPDeclarations::numParams(PyFunctionObject *func)
+{
+    _cacheFunction(func);
+
+    const cache_function_t *function = _getCachedFunction(func);
+    if (function == NULL)
+        return -1;
+
+    return function->parameters.size();
+}
+
+bool YCPDeclarations::exists(PyFunctionObject *func)
+{
+    _cacheFunction(func);
+
+    return _isInCache(func);
+}
+
+vector<constTypePtr> YCPDeclarations::params(PyFunctionObject *func)
+{
+    _cacheFunction(func);
+
+    const cache_function_t *function = _getCachedFunction(func);
+    if (function == NULL){
+        return vector<constTypePtr>();
+    }
+
+    return function->parameters;
+}
+
+constTypePtr YCPDeclarations::returnType(PyFunctionObject *func)
+{
+    _cacheFunction(func);
+
+    const cache_function_t *function = _getCachedFunction(func);
+    if (function == NULL){
+        return _interpretType("any");
+    }
+
+    return function->return_type;
+}
+/********** PUBLIC END **********/

Added: trunk/python-bindings/src/YCPDeclarations.h
URL: http://svn.opensuse.org/viewcvs/yast/trunk/python-bindings/src/YCPDeclarations.h?rev=41338&view=auto
==============================================================================
--- trunk/python-bindings/src/YCPDeclarations.h (added)
+++ trunk/python-bindings/src/YCPDeclarations.h Wed Oct 10 16:52:28 2007
@@ -0,0 +1,128 @@
+#ifndef _YCPDECLARATIONS_H_
+#define _YCPDECLARATIONS_H_
+
+#include <Python.h>
+#include <ycp/Type.h>
+#include <vector>
+#include <string>
+
+/**
+ * This class stores information about declarations in python module which were
+ * done by YCPDeclarations module (YCPDeclaratios.py).
+ * This is class is singelton and static method instance() returns pointer to
+ * object.
+ *
+ * All methods which return any information about declared functions are
+ * called with argument pointer to PyFunctionObject (which identifies
+ * function unambiguously.
+ *
+ * Example of usage:
+ *
+ *      #include "YCPDeclarations.h"
+ *
+ *      PyObject *func = PyDict_GetItemString(dict, "function");
+ *      YCPDeclarations *decl = YCPDeclarations::instance();
+ *      int num_params = decl->numParams((PyFunctionObject *)func);
+ *      ...
+ *
+ */
+class YCPDeclarations {
+  private:
+    /**
+     * structure where can be stored cached function.
+     */
+    typedef struct{
+        PyFunctionObject *function;
+        constTypePtr return_type;
+        std::vector<constTypePtr> parameters;
+    } cache_function_t;
+
+
+    /**
+     * Pointer to Python module YCPDeclarations.
+     */
+    PyObject *_py_self;
+
+    /**
+     * List of cached functions.
+     */
+    std::vector<cache_function_t *> _cache;
+
+
+
+    /**
+     * Private construct.
+     * Call YCPDeclarations::instance() to get pointer to YCPDeclarations
+     * object.
+     */
+    YCPDeclarations();
+
+    /**
+     * Return item from function map which has key key.
+     * Return borrowed reference!
+     */
+    PyObject *_getItemFromFunctionMap(PyObject *key);
+
+    /**
+     * Interpret string as YCP type.
+     * This method must be synchronized with variable
+     * YCPDeclare._available_types from YCPDeclarations.py!!
+     */
+    constTypePtr _interpretType(const char *) const;
+
+    /**
+     * Return true, if func is in internal cache.
+     */
+    bool _isInCache(PyFunctionObject *func) const;
+
+    /**
+     * Cache function func if it is not already cached.
+     */
+    void _cacheFunction(PyFunctionObject *func);
+
+    /**
+     * Return pointer to struct which defines cached function.
+     * Memory pointed by returned pointer must _not_ be deleted! It points
+     * into internal list.
+     */
+    const cache_function_t *_getCachedFunction(PyFunctionObject *func) const;
+
+  public:
+    ~YCPDeclarations();
+
+    /**
+     * Return number of parameters in declaration or -1 if function is not registered.
+     */
+    int numParams(PyFunctionObject *pointer_to_function);
+
+    /**
+     * Return true if function exists in YCPDeclarations module.
+     */
+    bool exists(PyFunctionObject *pointer_to_function);
+
+    /**
+     * Return list of YCP types corresponding with parameters fo function.
+     */
+    std::vector<constTypePtr> params(PyFunctionObject *pointer_to_function);
+
+    /**
+     * Return return YCP type of function.
+     */
+    constTypePtr returnType(PyFunctionObject *pointer_to_function);
+
+
+  //static
+  private:
+    /**
+     * Here is stored pointer to YCPDeclare object.
+     */
+    static std::auto_ptr<YCPDeclarations> _instance;
+  public:
+    /**
+     * Return pointer to instance of YCPDeclare object.
+     */
+    static YCPDeclarations *instance();
+};
+
+#endif
+/* vim: set sw=4 ts=4 et ft=cpp cindent : */

Added: trunk/python-bindings/src/YCPDeclarations.py
URL: http://svn.opensuse.org/viewcvs/yast/trunk/python-bindings/src/YCPDeclarations.py?rev=41338&view=auto
==============================================================================
--- trunk/python-bindings/src/YCPDeclarations.py (added)
+++ trunk/python-bindings/src/YCPDeclarations.py Wed Oct 10 16:52:28 2007
@@ -0,0 +1,102 @@
+"""
+ This module defines class YCPDeclare which can be used for defining
+ what return type and what types of arguments has function which will be
+ exported to YCP. For usage see YCPDeclare.__doc__.
+
+
+ Internal:
+ Important is variable _function_map which holds information about
+ functions. Contents of _function_map can be accessed from C:
+
+    PyObject *import = PyImport_ImportModule("YCPDeclarations");
+    PyObject *dict = PyModule_GetDict(import);
+    PyObject *func_map = PyDict_GetItemString(dict, "_function_map");
+    // now in func_map should be stored map describing functions declared by
+    // YCPDeclare
+
+ _function_map has form:
+    _function_map = {
+        pointer_to_function : {
+            "return_type" : "string",
+            "parameters" : [ list of strings representing types ]
+        }
+    }
+
+"""
+
+import inspect
+
+_function_map = {}
+def _addToFunctionMap(func_pointer, return_type, params_types):
+    global __function_map
+    _function_map[func_pointer] = {"return_type" : return_type,
+                                   "parameters" : params_types}
+
+class YCPDeclare:
+    """
+     Functor for definig return type and types of parameters
+     of function which will be exported into YCP. Best usage
+     is as decorator (see http://www.python.org/dev/peps/pep-0318).
+
+     Example of usage:
+         form YCPDeclarations import YCPDeclare
+
+         @YCPDeclare("string", "int", "int")
+         def function(i, ii):
+             \"\"\" Function which returns string a accept two
+                    integers as arguments. \"\"\"
+             return str(i+ii)
+    """
+
+    # tuple of types which can be used
+    # This list must be synchronized with
+    # YCPDeclarations::_interpretType function from YCPDeclarations.h!!
+    _available_types = (
+        "any",
+        "boolean",
+        "string",
+        "integer",
+        "term",
+        "symbol",
+        "path",
+        "float"
+    )
+
+    def __init__(self, return_type, *params_types):
+        self._return_type = ""
+        self._params = []
+
+        self._checkTypes((return_type,) + params_types)
+
+        self._return_type = return_type
+        self._params = params_types
+
+    def __call__(self, func):
+        """ Overridden operator() """
+
+        self._checkNumParams(func, len(self._params))
+
+        _addToFunctionMap(func, self._return_type, self._params)
+        return func
+
+
+    def _checkTypes(self, types):
+        """ Check if defined types are in _available_types """
+
+        _invalid_types = []
+        for type in types:
+            if type not in self._available_types:
+                _invalid_types.append(type)
+
+        if len(_invalid_types) != 0:
+            raise Exception("Unknnown types: " + str(_invalid_types))
+
+
+    def _checkNumParams(self, func, numTypes):
+        """ Check if number of parameters equals to number of defined types """
+
+        args = len(inspect.getargspec(func)[0])
+        if args != numTypes:
+            raise Exception("Number of declared types does not match number of arguments.")
+        
+

--
To unsubscribe, e-mail: yast-commit+unsubscribe@xxxxxxxxxxxx
For additional commands, e-mail: yast-commit+help@xxxxxxxxxxxx

< Previous Next >
This Thread
  • No further messages